%%-*- mode: erlang -*-
%% emqx_auth_http config mapping
{mapping, "auth.http.auth_req", "emqx_auth_http.auth_req", [
  {datatype, string}
]}.

{mapping, "auth.http.auth_req.method", "emqx_auth_http.auth_req", [
  {default, post},
  {datatype, {enum, [post, get]}}
]}.

{mapping, "auth.http.auth_req.content_type", "emqx_auth_http.auth_req", [
  {default, 'x-www-form-urlencoded'},
  {datatype, {enum, ['json', 'x-www-form-urlencoded']}}
]}.

{mapping, "auth.http.auth_req.params", "emqx_auth_http.auth_req", [
  {datatype, string}
]}.

{translation, "emqx_auth_http.auth_req", fun(Conf) ->
  case cuttlefish:conf_get("auth.http.auth_req", Conf, undefined) of
    undefined -> cuttlefish:unset();
    Url ->
      Params = cuttlefish:conf_get("auth.http.auth_req.params", Conf),
      [{url, Url},
      {method, cuttlefish:conf_get("auth.http.auth_req.method", Conf)},
      {content_type, list_to_binary("application/" ++ atom_to_list(cuttlefish:conf_get("auth.http.auth_req.content_type", Conf)))},
      {params, [list_to_tuple(string:tokens(S, "=")) || S <- string:tokens(Params, ",")]}]
  end
end}.

{mapping, "auth.http.super_req", "emqx_auth_http.super_req", [
  {datatype, string}
]}.

{mapping, "auth.http.super_req.method", "emqx_auth_http.super_req", [
  {default, post},
  {datatype, {enum, [post, get]}}
]}.

{mapping, "auth.http.super_req.content_type", "emqx_auth_http.super_req", [
  {default, 'x-www-form-urlencoded'},
  {datatype, {enum, ['json', 'x-www-form-urlencoded']}}
]}.

{mapping, "auth.http.super_req.params", "emqx_auth_http.super_req", [
  {datatype, string}
]}.

{translation, "emqx_auth_http.super_req", fun(Conf) ->
  case cuttlefish:conf_get("auth.http.super_req", Conf, undefined) of
    undefined -> cuttlefish:unset();
    Url -> Params = cuttlefish:conf_get("auth.http.super_req.params", Conf),
           [{url, Url}, {method, cuttlefish:conf_get("auth.http.super_req.method", Conf)},
            {content_type, list_to_binary("application/" ++ atom_to_list(cuttlefish:conf_get("auth.http.super_req.content_type", Conf)))},
            {params, [list_to_tuple(string:tokens(S, "=")) || S <- string:tokens(Params, ",")]}]
  end
end}.

{mapping, "auth.http.acl_req", "emqx_auth_http.acl_req", [
  {default, undefined},
  {datatype, string}
]}.

{mapping, "auth.http.acl_req.method", "emqx_auth_http.acl_req", [
  {default, post},
  {datatype, {enum, [post, get]}}
]}.

{mapping, "auth.http.acl_req.content_type", "emqx_auth_http.acl_req", [
  {default, 'x-www-form-urlencoded'},
  {datatype, {enum, ['json', 'x-www-form-urlencoded']}}
]}.

{mapping, "auth.http.acl_req.params", "emqx_auth_http.acl_req", [
  {datatype, string}
]}.

{translation, "emqx_auth_http.acl_req", fun(Conf) ->
  case cuttlefish:conf_get("auth.http.acl_req", Conf, undefined) of
    undefined -> cuttlefish:unset();
    Url -> Params = cuttlefish:conf_get("auth.http.acl_req.params", Conf),
           [{url, Url},
            {method, cuttlefish:conf_get("auth.http.acl_req.method", Conf)},
            {content_type, list_to_binary("application/" ++ atom_to_list(cuttlefish:conf_get("auth.http.acl_req.content_type", Conf)))},
            {params, [list_to_tuple(string:tokens(S, "=")) || S <- string:tokens(Params, ",")]}]
  end
end}.

{mapping, "auth.http.request.timeout", "emqx_auth_http.request_timeout", [
  {default, "5s"},
  {datatype, [integer, {duration, ms}]}
]}.

{mapping, "auth.http.pool_size", "emqx_auth_http.pool_opts", [
  {default, 8},
  {datatype, integer}
]}.

{mapping, "auth.http.request.connect_timeout", "emqx_auth_http.pool_opts", [
  {default, "5s"},
  {datatype, [integer, {duration, ms}]}
]}.

{mapping, "auth.http.ssl.cacertfile", "emqx_auth_http.pool_opts", [
  {datatype, string}
]}.

{mapping, "auth.http.ssl.certfile", "emqx_auth_http.pool_opts", [
  {datatype, string}
]}.

{mapping, "auth.http.ssl.keyfile", "emqx_auth_http.pool_opts", [
  {datatype, string}
]}.

{mapping, "auth.http.request.retry_times", "emqx_auth_http.pool_opts", [
  {default, 5},
  {datatype, integer}
]}.

{mapping, "auth.http.request.retry_interval", "emqx_auth_http.pool_opts", [
  {default, "1s"},
  {datatype, {duration, ms}}
]}.

{mapping, "auth.http.request.retry_backoff", "emqx_auth_http.pool_opts", [
  {default, 2.0},
  {datatype, float}
]}.

{translation, "emqx_auth_http.pool_opts", fun(Conf) ->
  Filter = fun(L) -> [{K, V} || {K, V} <- L, V =/= undefined] end,
  InfinityFun = fun(0) -> infinity;
                   (Duration) -> Duration
                end,
  SslOpts = Filter([{cacertfile, cuttlefish:conf_get("auth.http.ssl.cacertfile", Conf, undefined)},
                    {certfile, cuttlefish:conf_get("auth.http.ssl.certfile", Conf, undefined)},
                    {keyfile, cuttlefish:conf_get("auth.http.ssl.keyfile", Conf, undefined)}]),
  Opts = [{pool_size, cuttlefish:conf_get("auth.http.pool_size", Conf)},
          {connect_timeout, InfinityFun(cuttlefish:conf_get("auth.http.request.connect_timeout", Conf))},
          {retry, cuttlefish:conf_get("auth.http.request.retry_times", Conf)},
          {retry_timeout, cuttlefish:conf_get("auth.http.request.retry_interval", Conf)}],
  case SslOpts of
      [] -> Filter(Opts);
      _  ->
          TlsVers = ['tlsv1.2','tlsv1.1',tlsv1],
          DefaultOpts = [{versions, TlsVers},
                         {ciphers, lists:foldl(
                                       fun(TlsVer, Ciphers) ->
                                           Ciphers ++ ssl:cipher_suites(all, TlsVer)
                                       end, [], TlsVers)}],
          Filter([{ssl, DefaultOpts ++ SslOpts} | Opts])
  end
end}.


{mapping, "auth.http.header.$field", "emqx_auth_http.headers", [
  {datatype, string}
]}.

{translation, "emqx_auth_http.headers", fun(Conf) ->
  lists:map(
      fun({["auth", "http", "header", Field], Value}) ->
          {Field, Value}
      end,
      cuttlefish_variable:filter_by_prefix("auth.http.header", Conf))
end}.